/*
 * @Author: --
 * @Date: 2022-09-13 14:47:32
 * @LastEditors: kangzhou
 * @LastEditTime: 2022-09-13 14:47:33
 */
import qs from 'qs'
import axios, { AxiosDefaults, AxiosResponse } from 'axios'
import { blobToJson, getFileNameFromHeaders, getObjType } from '@/utils/helpers'
import { message } from 'ant-design-vue'

const instance = axios.create({
  baseURL: '/',
  headers: {
    'Content-Type': 'application/json',
    'X-Requested-With': 'XMLHttpRequest'
  },
  timeout: 1000 * 10
})

const handleException = (code: string|number) => {
  console.warn('出现异常:', code)
  let msg = ''
  switch (Number(code)) {
    case 401: msg = '未授权，请重新登录(401)'; break
    case 403: msg = '拒绝访问(403)'; break
    case 404: msg = '请求出错(404)'; break
    case 408: msg = '请求超时(408)'; break
    case 500: msg = '服务器错误(500)'; break
    case 501: msg = '服务未实现(501)'; break
    case 502: msg = '网络错误(502)'; break
    case 503: msg = '服务不可用(503)'; break
    case 504: msg = '网络超时(504)'; break
    case 505: msg = 'HTTP版本不受支持(505)'; break
    default: msg = `连接出错(${code})!`
  }
  return { errorMsg: msg }
}

instance.interceptors.request.use((config: any) => {
  const dataType = getObjType(config.data)
  const isFormUrlEncoded = config.headers['Content-Type'] === 'application/x-www-form-urlencoded'
  if (dataType === 'Object' && isFormUrlEncoded) {
    config.data = qs.stringify(config.data)
  }
  return config
}, (err) => {
  console.error(err)
  return Promise.reject(err)
})

instance.interceptors.response.use((res: AxiosResponse) => {
  if (res.status === 200) {
    const data = res.data
    const dataType = getObjType(data)
    if (dataType === 'Object') {
      const code = data.errorCode + ''
      // 表示成功
      if (code === '0') {
        return data.data
      } else {
        return Promise.reject(data)
      }
    } else if (dataType === 'Blob') {
      const isStream = res.request.response.type === 'application/octet-stream'
      if (isStream) {
        const fileName = getFileNameFromHeaders(res.headers)
        return { data, fileName }
      } else {
        return blobToJson(data).then((res: any) => {
          return Promise.reject(res)
        })
      }
    } else {
      return Promise.reject(data)
    }
  } else {
    return Promise.reject(handleException(res.status))
  }
}, (err) => {
  const status = err.request.status + ''
  return Promise.reject(handleException(status))
})

/**
 * api请求
 * @params config.url             请求链接
 * @params config.method          请求方式
 * @params config.headers         请求头
 * @params config.data            请求数据（post方法）
 * @params config.params          请求数据（get方法）
 * @params config.hideErr         接口异常是否不提示异常信息
 * @params config.blHandleErr     接口异常后页面是否需要处理
 *
 */
export default function(config: any) {
  return new Promise((resolve: any, reject: any) => {
    instance(config).then((res) => {
      resolve(res)
    }).catch((err: any) => {
      if (!config.hideErr) {
        message.warning(err.errorMsg)
      }
      if (config.blHandleErr) {
        reject(err)
      }
    })
  })
}
